package top.market.controller;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.sql.Order;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yungouos.pay.util.PaySignUtil;
import com.yungouos.pay.wxpay.WxPay;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import top.market.config.AliPayConfig;
import top.market.config.WxPayConfig;
import top.market.model.dto.OrderDTO;
import top.market.model.dto.PayBodyDataDTO;
import top.market.model.entity.OrderDetail;
import top.market.model.entity.OrderStatusEnum;
import top.market.model.entity.Orders;
import top.market.model.entity.Product;
import top.market.model.vo.OrderDetailVO;
import top.market.model.vo.OrdersVO;
import top.market.model.vo.ProductVo;
import top.market.model.vo.Result;
import top.market.service.IAddressBookService;
import top.market.service.IOrderDetailService;
import top.market.service.IOrdersService;
import top.market.service.IProductService;
import top.market.util.CurrentUserUtil;
import top.market.util.WeChatPayUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static net.sf.jsqlparser.util.validation.metadata.NamedObject.user;

/**
 * <p>
 * 订单表 前端控制器
 * </p>
 *
 * @author li yuhai
 * @since 2025-03-26
 */
@RestController
@RequestMapping("/order")
public class OrdersController {

    @Autowired
    private IOrdersService ordersService;

    @Autowired
    private IOrderDetailService orderDetailService;
    @Autowired
    private IProductService productService;

    // 订单支付
    @PostMapping("/nativePay")
    public Result pay(@RequestBody OrderDTO tOrder) {
        try {
            Orders order = new Orders();
            String body = tOrder.getBody();
            if (StrUtil.isBlank(body)) { return Result.error("商品信息错误"); }
            BeanUtils.copyProperties(tOrder, order);
            if (order.getAddressBookId() == null || order.getAddressBookId() < 0) { return Result.error("地址信息错误"); }
            Map data = ordersService.nativePayOrder(order);
            if (data != null &&  data.size() <= 0) { return Result.error("下单失败"); }
            return Result.ok("", data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.error("系统错误");
    }

    // pay支付订单信息
    @PostMapping("/yungouos/nativePay")
    public Result nativePay(@RequestBody OrderDTO tOrder) {
        try {
            Orders order = new Orders();
            String body = tOrder.getBody();
            if (StrUtil.isBlank(body)) {
                return Result.error("商品信息错误");
            }
            BeanUtils.copyProperties(tOrder, order);
            if (order.getAddressBookId() == null || order.getAddressBookId() < 0) {
                return Result.error("地址信息错误");
            }
            order = ordersService.yungouosNativePayOrder(order);
            if (order == null) {
                return Result.error("下单失败");
            }
            HashMap map = new HashMap<String, Object>();
            String notify_url = "http://yungouos.wicp.net/api/callback/notify";
            String result = WxPay.nativePay(order.getNumber(), order.getAmount().toPlainString(), WxPayConfig.mchId, body, "2", null, notify_url, null, null, null, null, null, null, WxPayConfig.key);
            map.put("url", result);
            map.put("orderNo", order.getNumber());
            Result.ok("",  map);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.error("系统错误");
    }


    // 根据状态来查询订单  order/queryOrdersCheckStatus
    @GetMapping("/queryOrdersCheckStatus")
    public Result queryOrdersCheckStatus(
            @RequestParam("payStatus") Integer status,
            @RequestParam("pageNum") Integer pageNum,
            @RequestParam("pageSize") Integer pageSize
    ) {
        Page<Orders> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<Orders> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Orders::getUserId, CurrentUserUtil.getCustomUserDetails().getId());
        wrapper.eq(Orders::getStatus, status);
        List<Orders> list = ordersService.list(page, wrapper);
        return Result.ok("", list);
    }

    // 直接查询所有的订单信息  order/list
    @GetMapping("/list")
    public Result list() {
        LambdaQueryWrapper<Orders> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Orders::getUserId, CurrentUserUtil.getCustomUserDetails().getId());
        List<Orders> list = ordersService.list(wrapper);
        // 将orders转为ordersVo
        List<OrdersVO> ordersVOList = getOrdersVOList(list);
        return Result.ok("", ordersVOList);
    }

    // 待收货订单
    @GetMapping("/watingPayment")
    public Result watingPayment() {
        LambdaQueryWrapper<Orders> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Orders::getUserId, CurrentUserUtil.getCustomUserDetails().getId());
        wrapper.eq(Orders::getStatus, OrderStatusEnum.PENDING_PAYMENT);
        List<Orders> list = ordersService.list(wrapper);
        // 将orders转为ordersVo
        List<OrdersVO> ordersVOList = getOrdersVOList(list);
        return Result.ok("", ordersVOList);
    }

    // 待收货订单
    @GetMapping("/yijiedan")
    public Result yijiedan() {
        LambdaQueryWrapper<Orders> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Orders::getUserId, CurrentUserUtil.getCustomUserDetails().getId());
        wrapper.eq(Orders::getStatus, OrderStatusEnum.CONFIRMED);
        List<Orders> list = ordersService.list(wrapper);
        // 将orders转为ordersVo
        List<OrdersVO> ordersVOList = getOrdersVOList(list);
        return Result.ok("", ordersVOList);
    }

    // 待收货订单
    @GetMapping("/paisongzhong")
    public Result paisongzhong() {
        LambdaQueryWrapper<Orders> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Orders::getUserId, CurrentUserUtil.getCustomUserDetails().getId());
        wrapper.eq(Orders::getStatus, OrderStatusEnum.DELIVERING);
        List<Orders> list = ordersService.list(wrapper);
        // 将orders转为ordersVo
        List<OrdersVO> ordersVOList = getOrdersVOList(list);
        return Result.ok("", ordersVOList);
    }

    // 待收货订单
    @GetMapping("/yiwancheng")
    public Result yiwancheng() {
        LambdaQueryWrapper<Orders> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Orders::getUserId, CurrentUserUtil.getCustomUserDetails().getId());
        wrapper.eq(Orders::getStatus, OrderStatusEnum.COMPLETED);
        List<Orders> list = ordersService.list(wrapper);
        // 将orders转为ordersVo
        List<OrdersVO> ordersVOList = getOrdersVOList(list);
        return Result.ok("", ordersVOList);
    }


    // getCurrentOrders
    //     PENDING_CONFIRMATION(2, "待接单"),
    //    CONFIRMED(3, "已接单"),
    //    DELIVERING(4, "派送中"),
    @GetMapping("/current")
    public Result getCurrentUserOrders() {
        LambdaQueryWrapper<Orders> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Orders::getUserId, CurrentUserUtil.getCustomUserDetails().getId());
        List<OrderStatusEnum> statusList = Arrays.asList(OrderStatusEnum.CONFIRMED, OrderStatusEnum.DELIVERING, OrderStatusEnum.PENDING_CONFIRMATION, OrderStatusEnum.PENDING_PAYMENT);
        wrapper.in(Orders::getStatus, statusList);
        List<Orders> list = ordersService.list(wrapper);
        List<OrdersVO> ordersVOList = getOrdersVOList(list);
        return Result.ok("", ordersVOList);
    }


    // 根据id获取订单详情, 订单详情中包含多个商品
    @GetMapping("/detail/{id}")
    public Result detail(@PathVariable("id") Long id) {
        LambdaQueryWrapper<Orders> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Orders::getUserId, CurrentUserUtil.getCustomUserDetails().getId());
        wrapper.eq(Orders::getId, id);
        Orders orders = ordersService.getOne(wrapper);
        OrdersVO ordersVO = new OrdersVO();
        BeanUtils.copyProperties(orders, ordersVO);
        LambdaQueryWrapper<OrderDetail> orderDetailQuery = new LambdaQueryWrapper<>();
        orderDetailQuery.eq(OrderDetail::getOrderId, orders.getId());
        List<OrderDetail> orderDetailList = orderDetailService.list(orderDetailQuery);
        List<OrderDetailVO> orderDetailVOList = orderDetailList.stream().map(orderDetail -> {
            OrderDetailVO orderDetailVO = new OrderDetailVO();
            BeanUtils.copyProperties(orderDetail, orderDetailVO);
            LambdaQueryWrapper<Product> productQuery = new LambdaQueryWrapper<>();
            productQuery.eq(Product::getId, orderDetail.getProductId());
            List<Product> productList = productService.list(productQuery);
            Product product = productList.get(0);
            ProductVo productVo = new ProductVo();
            BeanUtils.copyProperties(product, productVo);
            orderDetailVO.setProduct(productVo);
            return orderDetailVO;
        }).collect(Collectors.toList());
        ordersVO.setOrderDetailsList(orderDetailVOList);
        return Result.ok("", ordersVO);
    }


    // 抽象出来的方法，因为都是查询，不需要事务控制
    private List<OrdersVO> getOrdersVOList(List<Orders> list) {
        List<OrdersVO> ordersVOList = list.stream().map(item -> {
            OrdersVO ordersVO = new OrdersVO();
            BeanUtils.copyProperties(item, ordersVO);
            LambdaQueryWrapper<OrderDetail> orderDetailQuery = new LambdaQueryWrapper<>();
            orderDetailQuery.eq(OrderDetail::getOrderId, ordersVO.getId());
            List<OrderDetailVO> orderDetailVOList = orderDetailService.list(orderDetailQuery).stream().map(orderDetail -> {
                OrderDetailVO orderDetailVO = new OrderDetailVO();
                BeanUtils.copyProperties(orderDetail, orderDetailVO);
                LambdaQueryWrapper<Product> productQuery = new LambdaQueryWrapper<>();
                productQuery.eq(Product::getId, orderDetail.getProductId());
                Product product = productService.getOne(productQuery);
                ProductVo productVo = new ProductVo();
                BeanUtils.copyProperties(product, productVo);
                orderDetailVO.setProduct(productVo);
                return orderDetailVO;
            }).collect(Collectors.toList());
            ordersVO.setOrderDetailsList(orderDetailVOList);
            return ordersVO;
        }).collect(Collectors.toList());
        return ordersVOList;
    }

}
